#include "esp8266.h"
#include "OLED.h"

// esp8266初始化串口2,设置波特率
// 复位esp8266,关闭命令回显
ESP_RET ESP8266_Init(uint32_t Baud)
{
    ESP_RET retval = ESP_NONE;
    UART2_Init(Baud); // 初始化串口2用于与ESP8266通信
	TIM4_DelayInit(); // 用作命令的延迟
    // 使能空闲中断
    USART_ITConfig(UART2,USART_IT_IDLE,ENABLE);
    
    // 发送命令复位ESP8266
    if(ESP_OK != (retval= ESP_SendCmd("AT+RST\r\n")))
    {
        return retval;
    }
	TIM4_Delayms(1000);
	
    // 时关闭命令回显
	ESP_SendCmd("ATE0\r\n");
	TIM4_Delayms(500);
    return retval; 
}

// 封装一个esp8266使用的命令发送函数
// 返回ESP_OK表示命令执行成功
// 返回ESP_ERR表示命令错误
ESP_RET ESP_SendCmd(const char *cmd)
{
    uint8_t i;
    ESP_RET retval = ESP_NONE;
    
    for(i=0;cmd[i] != '\0';i++)
    {
        Uart2_SendByte(cmd[i]); // 发送数据
    }
    while(ESP_RxFlag != 1); // 等待回传的数据 
    if(strstr((char *)ESP_RxData,"OK") != NULL){
        retval = ESP_OK;
    }
    else if(strstr((char *)ESP_RxData,"ERROR") != NULL){
        retval = ESP_ERR;
    }
    else{
		retval = ESP_NONE;
	}

    ESP_RxFlag = 0; // 清空接收标志位
    return retval;
}


// esp8266链接WIFI热点(STA模式)
// 成功返回ESP_OK，失败返回错误原因
ESP_RET ESP_ConnectWIFI(char *ssid,char * passwd)
{
    ESP_RET retval = ESP_NONE;
    char WIFI_MSG[30] = "";
	// AT+CWMODE=1 STA模式,用于连接AP
    if(ESP_OK != (retval= ESP_SendCmd("AT+CWMODE=1\r\n")))
    {
        return retval;
    }
	TIM4_Delayms(500);
	
    sprintf(WIFI_MSG,"AT+CWJAP_CUR=\"%s\",\"%s\"\r\n",ssid,passwd);
    ESP_SendCmd(WIFI_MSG); // 发送连接WIFI命令
	while(ESP_RxFlag != 1);
	if(strstr((char *)ESP_RxData,"WIFI") != NULL){
		if(strstr((char *)ESP_RxData,"CONNECTED") != NULL)
		{
			retval = ESP_OK;
            TIM4_Delayms(3000); // 等待剩余信息发送完成
		}else{
			ESP_RxFlag = 0; // 再等待一次接收,判断是否成功连接
			while(ESP_RxFlag != 1);
			if(strstr((char *)ESP_RxData,"CONNECTED") != NULL)
			{
				retval = ESP_OK;
                TIM4_Delayms(3000); // 等待剩余信息发送完成
			}else{
				retval = ESP_ERR;
			}
		}
    }else{
		retval = ESP_ERR;
	}
	
	ESP_RxFlag = 0; // 清除接收标志
    return retval;
}

// 创建TCP链接，设置单路连接
ESP_RET ESP_TcpConnect(char *ipaddr,int port)
{
    ESP_RET retval = ESP_NONE;
    char TCP_MSG[30] = "";
    if(ESP_OK != (retval = ESP_SendCmd("AT+CIPMUX=0\r\n"))) // 开启单路连接模式
    {
        retval = ESP_ERR;
    }
    
    TIM4_Delayms(1000);
    
    sprintf(TCP_MSG,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",ipaddr,port);
    
    if(ESP_OK != (retval = ESP_SendCmd(TCP_MSG))) // 连接TCP服务器
    {
        retval =  ESP_ERR;
    }
    TIM4_Delayms(1000);
    return retval;
}

// 检查连接状态
ESP_STATUS ESP_CheckConnect(void)
{
    ESP_STATUS retval = ESP_NULL;
    char *num = NULL; 
    
    ESP_SendCmd( "AT+CIPSTATUS\r\n");
    if(strstr((char *)ESP_RxData,"STATUS") != NULL)
    {
        num = strtok((char *)ESP_RxData,"##");
        strtok(num,":");
        num = strtok(NULL,":");
        retval = (ESP_STATUS)(atoi(num));
    }
    return retval;
}

// 开启透传模式，发送请求并获取数据
ESP_RET ESP_TcpGetWeather(char *Key,char *City,W_MSG *weather)
{
    ESP_RET ret_val = ESP_NONE;
	char Quest[256];
	char buf[300]; // 接收到的数据
	char cmd[30];
	char temp[3];
	uint8_t i,count = 0; // count 超时退出
	sprintf(Quest,xinzhi_api,Key,City); // 封装命令
    // 设置为透传模式
    if(ESP_OK != (ret_val = ESP_SendCmd("AT+CIPMODE=0\r\n")))
    {
        ret_val = ESP_ERR;
    }
	
	TIM4_Delayms(500);
	sprintf(cmd,"AT+CIPSEND=%d\r\n",strlen(Quest)); // 发送获取请求
	// 开启发送
	if(ESP_OK != ESP_SendCmd(cmd))
	{
		return ESP_ERR;
	}
    else
    {
        TIM4_Delayms(10);
        for(i = 0; Quest[i] != '\0'; i++)
        {
            Uart2_SendByte(Quest[i]);
        }
        while(1)
        {  
            if(ESP_RxFlag == 1)
            {         
               ESP_RxFlag = 0; // 接收完成，清空标志位
               count = 0; //有效接收,清0 ;
               strcpy(buf,(char *)ESP_RxData); // 保存数据  
               if(strstr(buf,"results") != NULL)
                {        
                    ret_val = ESP_OK;
                    break;
                }         
            }
            count++;
            TIM4_Delayms(20);
            if(count >= 100)  // 2秒超时退出
            {
                ret_val = ESP_ERR;
                break;
            }
        }
	}

	// 解析返回的数据
    if(ret_val == ESP_OK)
    {
    	AnalysisData(buf,strlen(buf),"id",weather->id);
        AnalysisData(buf,strlen(buf),"name",weather->name);
        AnalysisData(buf,strlen(buf),"country",weather->country);
        AnalysisData(buf,strlen(buf),"text",weather->text);
        AnalysisData(buf,strlen(buf),"temp",temp);
        sscanf(temp,"%d",&weather->temp);
    }    
    return ret_val;
}


// 解析数据
// buf: 解析的数据源
// tag： 解析的对象
// result：解析得到的结果
// 返回-1表示解析错误,返回0表示成功
int AnalysisData(const char *buf, int len,char *tag,char *result)
{
	char *p = NULL; // 用于解析结果
	char temp[300];
	strncpy(temp,buf,len);
	if(NULL != (p = strstr(temp,tag)))
	{
		p = strtok(p,",");
		strtok(p,":");
		p = strtok(NULL,":");
		p[strlen(p)-1] = '\0';
		p = p+1;
		strcpy(result,p);
	}else{
		return -1;
	}
	return 0;
}
